/*
 * REFIOEventContext.h
 *
 *  Created on: Jun 5, 2013
 *      Author: Lucifer
 */

#ifndef REFIOEVENTCONTEXT_H_
#define REFIOEVENTCONTEXT_H_

#ifdef	BFX_IO_HAS_IOCP
#include <mswsock.h>
#endif


namespace BFX
{

class REFIOEventContext;
typedef	Delegate<void (REFIOEventContext*)>	IOEventCallback;

#ifdef	BFX_IO_HAS_IOCP

////////////////////////////////////////////////////////////////////////////////
// REFIOEventContext

class REFIOEventContext : public REFObject, public OVERLAPPED
{
public:
	REFIOEventContext(IOEventCallback callback)
	{
		m_nErrorCode = 0;
		m_callback = callback;

		Reset();
	}

	virtual void Complete(int nErrorCode, int nBytesTransferred) = 0;

	void Reset()
	{
		Internal = 0;
		InternalHigh = 0;
		Offset = 0;
		OffsetHigh = 0;
		hEvent = 0;
		m_lCompleted = 0;
	}

	/**
	 * The system error code.
	 * Windows uses GetLastError(), other systems uses errno.
	 * @return
	 */
	int GetErrorCode() const
	{
		return m_nErrorCode;
	}
	void SetErrorCode(int nErrorCode)
	{
		m_nErrorCode = nErrorCode;
	}

protected:
	int	m_nErrorCode;
	IOEventCallback	m_callback;

	friend class REFIOEventService;
	long	m_lCompleted;
	int		m_nBytesTransferred;
};

#else	//	BFX_IO_HAS_IOCP

////////////////////////////////////////////////////////////////////////////////
// REFIOEventContext

class REFIOEventContext : public REFObject
{
public:
	REFIOEventContext(IOEventCallback callback)
	{
		m_nErrorCode = 0;
		m_callback = callback;
	}

	virtual bool Perform() = 0;

	void Complete()
	{
		m_callback(this);
	}

	/**
	 * The system error code.
	 * Windows uses GetLastError(), other systems uses errno.
	 * @return
	 */
	int GetErrorCode() const
	{
		return m_nErrorCode;
	}
	void SetErrorCode(int nErrorCode)
	{
		m_nErrorCode = nErrorCode;
	}

protected:
	int	m_nErrorCode;
	IOEventCallback	m_callback;
};

#endif	//	!BFX_IO_HAS_IOCP

} /* namespace BFX */
#endif /* REFIOEVENTCONTEXT_H_ */
